iT邦幫忙

2024 iThome 鐵人賽

DAY 26
0
Modern Web

React 學得動嗎系列 第 26

[Day 26] Gym Pro:性能優化

  • 分享至 

  • xImage
  •  

今天,我們來為系統進行一些優化和安全性增強,對於打造一個穩定、高效、安全的系統是一定要做的。

1. 資料庫查詢優化

首先,我們來優化一些常用的資料庫查詢,以提高系統的響應速度。

優化會員查詢

src/services/memberService.ts 中:

import { prisma } from '../lib/prisma';

export const getMembers = async (page: number, pageSize: number) => {
  const members = await prisma.member.findMany({
    take: pageSize,
    skip: (page - 1) * pageSize,
    select: {
      id: true,
      name: true,
      email: true,
      joinDate: true,
      membershipType: true,
    },
    orderBy: {
      joinDate: 'desc',
    },
  });

  const total = await prisma.member.count();

  return { members, total };
};

這裡我們使用了分頁和選擇性查詢來優化大量會員資料的獲取。

2. 增加緩存機制

接下來,我們使用 Redis 來實現緩存機制,減少對資料庫的直接查詢。

首先,安裝 Redis 客戶端:

npm install redis

然後,在 src/lib/redis.ts 中設置 Redis 客戶端:

import { createClient } from 'redis';

const redisClient = createClient({
  url: process.env.REDIS_URL
});

redisClient.on('error', (err) => console.log('Redis Client Error', err));

await redisClient.connect();

export { redisClient };

現在,我們可以在服務中使用 Redis 緩存:

import { redisClient } from '../lib/redis';
import { prisma } from '../lib/prisma';

export const getMember = async (id: string) => {
  const cacheKey = `member:${id}`;
  
  // 嘗試從緩存獲取數據
  const cachedMember = await redisClient.get(cacheKey);
  if (cachedMember) {
    return JSON.parse(cachedMember);
  }

  // 如果緩存中沒有,從資料庫獲取
  const member = await prisma.member.findUnique({
    where: { id: parseInt(id) },
  });

  if (member) {
    // 將資料存入緩存,設置過期時間為 1 小時
    await redisClient.set(cacheKey, JSON.stringify(member), {
      EX: 3600
    });
  }

  return member;
};

3. 輸入驗證

為了增強系統的安全性和穩定性,我們需要對用戶輸入進行嚴格的驗證。我們可以使用 Zod 來實現這一點。

首先,安裝 Zod:

npm install zod

然後,在 src/schemas/memberSchema.ts 中定義驗證模式:

import { z } from 'zod';

export const createMemberSchema = z.object({
  name: z.string().min(2, '姓名至少需要 2 個字元'),
  email: z.string().email('請輸入有效的電子郵件地址'),
  membershipType: z.enum(['basic', 'premium', 'vip']),
});

export type CreateMemberInput = z.infer<typeof createMemberSchema>;

在 API 路由中使用這個驗證模式:

import { createMemberSchema } from '../schemas/memberSchema';

app.post('/api/members', async (req, res) => {
  try {
    const input = createMemberSchema.parse(req.body);
    // 處理創建會員的邏輯...
  } catch (error) {
    if (error instanceof z.ZodError) {
      res.status(400).json({ errors: error.errors });
    } else {
      res.status(500).json({ error: '伺服器錯誤' });
    }
  }
});

小結

今天我們為 Gym Pro 系統實現了一些優化和安全性增強措施:

  1. 優化了資料庫查詢,提高了系統響應速度。
  2. 使用 Redis 實現了緩存機制,減少了對資料庫的直接查詢。
  3. 使用 Zod 實現了嚴格的輸入驗證,增強了系統的穩定性。

上一篇
[Day 25] Gym Pro:會員積分系統與課程預約功能
下一篇
[Day 27] Gym Pro:優化用戶體驗與增加實用功能
系列文
React 學得動嗎30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言